/*
 * HttpClientXml.cs
 * SinoGame
 * Created by com.sino on #CREATEONDATE#.
 */

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using System.Xml;
using System.IO;
using System.Text;
using UnityEngine.EventSystems;
using System.Security.Cryptography;
using VFramework;
public enum RequestType
{
	POST = 0,
	GET = 1,
}
public enum HttpRspErrorType{
	NET_ERROR = -1,
	PARSE_ERROR = -2,
}
	
public class HttpRsp{

	public int backCode = -1;
	public string errorDesc = "";

	public XmlNode body = null;
	public XmlNode content = null;

	public string cmd = "";
	public HttpRsp(){
			
	}
	public HttpRsp(int code, string des , string cmd){
		backCode = code;
		errorDesc = des;
	}

	public HttpRsp(string xmlStr , string cmd){
		XmlDocument xd = new XmlDocument ();
		xd.LoadXml (xmlStr);

		backCode = int.Parse (xd.SelectSingleNode("root/body/backCode").InnerText);
		if (backCode != 0)
			errorDesc = xd.SelectSingleNode ("root/body/errorDesc").InnerText;
		else {
			content = xd.SelectSingleNode ("root/body/response");
			body = xd.SelectSingleNode ("root/body");
		}



	}

	public string errorMsg(){
		return errorDesc;
	}
}

public class HttpClientXml : MonoBehaviour
{

	public static string partnerId = "100001";
	public static string xmlVer = "4153V1.0.1.003";
	public static string ssId = "";
	public static string userID = "";
	public static string ticket = "";

	private Queue<KeyValuePair<RequestType, HttpRequest>> requestQueue = new Queue<KeyValuePair<RequestType, HttpRequest>> ();

	/*------------------------------------------------------------------------------------------------*/
	private float progress = 0;

	void Start()
	{
		//requestQueue = new Queue<KeyValuePair<RequestType, HttpRequest>>();
	}

	void Update()
	{
		if (requestQueue.Count > 0) {
			KeyValuePair<RequestType, HttpRequest> hr = requestQueue.Dequeue ();
			if (hr.Key == RequestType.POST) {
				//POST
				StartCoroutine (POST (hr.Value.url, hr.Value.cmd, hr.Value.data, hr.Value.callback));
//				Post2(hr.Value.url, hr.Value.cmd, hr.Value.data, hr.Value.callback);
			} else if (hr.Key == RequestType.GET) {
				//GET
//				StartCoroutine (GET (hr.Value.url, hr.Value.data, hr.Value.callback));
			}
		}
	}

	/// <summary>
	/// 加入请求队列
	/// </summary>
	/// <param name="type">Type.</param>
	/// <param name="hr">Hr.</param>
	protected void AddRequest(RequestType type, HttpRequest hr)
	{
		requestQueue.Enqueue (new KeyValuePair<RequestType, HttpRequest> (type, hr));
	}

	protected void ShowWaiting(bool st)
	{
		if (st == true)
			VUICommonDisplay.showLoaddingIndicate ();
		else {
			VUICommonDisplay.hideLoaddingIndicate ();
		}
	}

	public float Progress()
	{
		return progress;
	}

	protected void Print(string url, Dictionary<string,string> p)
	{
		string info = "";
		info += "Send:>>" + url + "\n";
		foreach (string k in p.Keys) {
			info += string.Format ("{0}={1}\n", k, p [k]);
		}
		Debug.Log (info);
	}

	/// <summary>
	/// post请求
	/// </summary>
	/// <param name="url">URL.</param>
	/// <param name="cmd">Cmd.</param>
	/// <param name="data">Data.</param>
	/// <param name="callback">Callback.</param>
	protected IEnumerator POST(string url, string cmd, Dictionary<string,string> data, Action<HttpRsp> callback)
	{
		Print (url, data);
		ShowWaiting (true);

		string sendString = GenXmlString (partnerId, xmlVer, ssId, cmd, data);
		Debug.Log ("sendXml : " + sendString);

		Security security = new Security ();
		byte[] sendBuffer;
		sendBuffer = System.Text.Encoding.UTF8.GetBytes (sendString);
		security.Encrypt (ref sendBuffer);

		WWW www = new WWW (url,sendBuffer);
		yield return www;
		ShowWaiting (false);

		byte[] recBuffer = www.bytes;

		string result = "";
		security.UnEncrypt (ref recBuffer);
		result = System.Text.Encoding.UTF8.GetString (recBuffer);

		if (result.StartsWith ("<?xml")) {
			try {
				Debug.Log(result);
				HttpRsp rsp = new HttpRsp (result,cmd);
				if (callback != null) requestCallback(rsp,callback);
			} catch (Exception e) {
				Debug.Log (e);
				if (callback != null) requestCallback(new HttpRsp((int)HttpRspErrorType.PARSE_ERROR,"xml解析错误!",cmd),callback);
			}
		} else {
			if (callback != null) requestCallback(new HttpRsp((int)HttpRspErrorType.NET_ERROR,"网络错误,请联系服务人员。",cmd),callback);
		}
	}

	void requestCallback( HttpRsp rsp, Action<HttpRsp> cb){
		if (rsp.backCode == 11020109) {
			if (!VUICommonDisplay.showTip (rsp.errorMsg())) {
				cb (rsp);
			} else {
				StartCoroutine(Util.DelayRun(delegate(object obj) {
					Debug.Log("游戏退出了");
					Application.Quit();
				},2));
			}
		} else {
			cb (rsp);
		}

	}

	/// <summary>
	/// 计算字符串的MD5值
	/// </summary>
	public static string MD5 (string source)
	{
		MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider ();
		byte[] data = System.Text.Encoding.UTF8.GetBytes (source);
		byte[] md5Data = md5.ComputeHash (data, 0, data.Length);
		md5.Clear ();

		string destString = "";
		for (int i = 0; i < md5Data.Length; i++) {
			destString += System.Convert.ToString (md5Data [i], 16).PadLeft (2, '0');
		}
		destString = destString.PadLeft (32, '0');
		return destString;
	}


	protected string GenXmlString(string partnerId, string ver, string ssId, string cmd, Dictionary<string,string> data)
	{
		StringBuilder xmlData = new StringBuilder ("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

		xmlData.Append ("<root>");
		//head
		StringBuilder head = new StringBuilder ();
		head.Append ("<head>");
		head.AppendFormat ("<partnerId>{0}</partnerId>", partnerId);
		head.Append ("</head>");
		xmlData.Append (head);

		StringBuilder body = new StringBuilder ();
		body.Append ("<body>");
		body.AppendFormat ("<ver>{0}</ver>", ver);
		body.AppendFormat ("<ssId>{0}</ssId>", ssId);
		body.AppendFormat ("<cmd>{0}</cmd>", cmd);

		StringBuilder request = new StringBuilder ();
		foreach (KeyValuePair<string,string> kv in data) {
			request.AppendFormat ("<{0}>{1}</{2}>", kv.Key, kv.Value, kv.Key);
		}
		body.AppendFormat ("<request>{0}</request>", request);

		body.Append ("</body>");
		xmlData.Append (body);

		string signStr = body.ToString ().Remove (0, 6);
		signStr = signStr.Remove (signStr.Length - 7);
		string sign = MD5 (signStr);
		xmlData.AppendFormat ("<sign>{0}</sign>", sign);
		xmlData.Append ("</root>");
		return xmlData.ToString ();
	}
}